package att_java ;

import java.io.* ;
import java.util.* ;

/**
 * Définit une TDS (Table des Symboles) servant de base aux TDC (Table des
 * Classes), TDA (Table des Attributs), TDM (Table des Methodes) et TDV (Table
 * des Variables).
 *
 * @param <INFO_SYMBOLE>
 */
public abstract class TDS<INFO_SYMBOLE extends INFO> {

	/**
	 * TDS de même nature que cette TDS et étendue par cette TDS.
	 */
	protected TDS<INFO_SYMBOLE> parente ;
	
	/**
	 * Vecteur contenant les instances de INFO_SYMBOLE contenues dans cette
	 * TDS. Le choix d'un vecteur permet de conserver l'ordre dans lequel sont
	 * insérée ces instances (ce qui est particulièrement utile pour les TDC,
	 * TDA et TDM).
	 */
	protected Vector<INFO_SYMBOLE> table ;
	
	public TDS ( ) {
		
		this.parente = null ;
		this.table = new Vector<INFO_SYMBOLE>() ;
		
	}
	
	public TDS (TDS<INFO_SYMBOLE> parente) {
		
		this.parente = parente ;
		this.table = new Vector<INFO_SYMBOLE>() ;
		
	}
	
	/**
	 * Insère une instance de INFO_SYMBOLE dans cette TDS.
	 * 
	 * @param symbole Instance de INFO_SYMBOLE à insérer.
	 */
	public void inserer (INFO_SYMBOLE symbole) {
		
		this.table.add(symbole) ;
		
	}
	
	/**
	 * Retourne l'instance de INFO_SYMBOLE de nom nom_symbole insérée dans
	 * cette TDS ou dans une TDS parente. Retourne null si elle n'existe pas.
	 * 
	 * @param  nom_symbole Nom de l'instance de INFO_SYMBOLE recherchée.
	 * @return Instance de INFO_SYMBOLE de nom nom_symbole insérée dans cette
	 *         TDS ou dans une TDS parente. null si elle n'existe pas.
	 */
	public INFO_SYMBOLE chercher (String nom_symbole) {
		
		INFO_SYMBOLE symbole = chercherLocalement(nom_symbole) ;
		
		if (symbole == null && this.parente != null) {
			symbole = this.parente.chercher(nom_symbole) ;
		}
		
		return symbole ;
		
	}
	
	/**
	 * Retourne l'instance de INFO_SYMBOLE de nom nom_symbole insérée dans
	 * cette TDS. Retourne null si elle n'existe pas.
	 * 
	 * @param  nom_symbole Nom de l'instance de INFO_SYMBOLE recherchée.
	 * @return Instance de INFO_SYMBOLE de nom nom_symbole insérée dans cette
	 *         TDS. null si elle n'existe pas.
	 */
	public INFO_SYMBOLE chercherLocalement (String nom_symbole) {
		
		INFO_SYMBOLE symbole = null ;
		
		for (INFO_SYMBOLE symbole_tmp : this.table) {
			if (symbole_tmp.getNom().equals(nom_symbole))
				symbole = symbole_tmp ;
		}
		
		return symbole ;
		
	}
	
	/**
	 * Enregitre le contenu de cette TDS dans un fichier nommé nom_fichier.
	 * 
	 * @param nom_fichier Nom du fichier.
	 */
	public void enregistrer (String nom_fichier) {
		
		try {
			
			PrintWriter pw = new PrintWriter(new FileOutputStream(nom_fichier));
            pw.print(this);
            pw.close();
			
		} catch (Exception e) { e.printStackTrace() ; }
		
	}
	
	public String toString ( ) {
		
		return this.toString("") ;
		
	}
	
	public String toString (String prefix) {
		
		String text = "" ;
		
		for (INFO_SYMBOLE symbole : this.table) {
			text = text + symbole.toString(prefix) ;
		}
		
		return text ;
		
	}
	
}
